import random
import torch

def data_iter_random(texts_idx, batch_size, num_steps):
    """
    创建一个随机迭代器，用于批量处理文本数据。

    参数:
    texts_idx (list of int): 文本数据的索引列表。
    batch_size (int): 批量大小。
    num_steps (int): 每个样本的步数（长度）。

    生成器输出:
    (torch.tensor, torch.tensor): 输入数据X和目标数据Y的批量，均为张量形式。
    """
    # 计算可以生成的样本数量
    num_examples = (len(texts_idx) - 1) // num_steps
    # 计算每个epoch中包含的批量数量
    epoch_size = num_examples // batch_size
    # 生成样本索引列表
    example_idx = list(range(num_examples))
    # 打乱样本索引顺序，以增加数据的随机性
    random.shuffle(example_idx)

    def _data(pos):
        """
        根据位置提取数据。

        参数:
        pos (int): 起始位置索引。

        返回:
        list of int: 从起始位置开始，长度为num_steps的数据列表。
        """
        return texts_idx[pos: pos + num_steps]

    # 遍历每个批量
    for i in range(epoch_size):
        # 计算当前批量的起始索引
        i = i * batch_size
        # 提取当前批量的样本索引
        batch_idx = example_idx[i: i + batch_size]
        # 根据样本索引提取输入数据X
        X = [_data(j * num_steps) for j in batch_idx]
        # 根据样本索引提取目标数据Y，目标数据是输入数据的下一个字符
        Y = [_data(j * num_steps + 1) for j in batch_idx]

        # 以张量的形式输出当前批量的输入数据X和目标数据Y
        yield torch.tensor(X), torch.tensor(Y)
